﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace UrlChecker.Check
{
    public partial class ucURL : UserControl
    {
        #region Attributes

        private Thread myThread = null;
        private delegate void myDeleGateListView(QT.SEO.SearchResult Result, string sid, string SearchEngine, string url);
        private delegate void myDeleGateButton(bool b);
        private delegate void myDeleGateInitProgressBar(string s, int max);
        private delegate void myDeleGateSetProgressBar(string s);
        private static ManualResetEvent Threadmre = new ManualResetEvent(true);

        private string FormatProgress = "{0}：{1}/{2}";
        private string FormatMsg = "{0}：收录量：{2}({1})";
        private string LastRecord = "0";
        private int thisRecord = 0;

        #endregion

        #region ucURL

        public ucURL()
        {
            InitializeComponent();
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            this.pbClose.Location = new Point(this.Width - this.pbClose.Width - 3, 3);
            this.pGroup.Location = new Point((this.Width - this.pGroup.Width) / 2, (this.Height - this.pGroup.Height) / 3);
        }

        protected override void  OnLeave(EventArgs e)
        {
            base.OnLeave(e);
            if (myThread != null && myThread.IsAlive) myThread.Abort();
        }

        #endregion

        #region Event

        #region Button

        private bool IsPause = false;
        List<string> SelectionGroups = new List<string>(QT.SEO.Setting.Get("DefaultGroupForCheckSnapShot").Split('|'));
        List<string> SelectionGroupNames = new List<string>();

        private void btnStart_Click(object sender, EventArgs e)
        {            
            int ColumnsCount = 3;
            int ColumnWidth = 140;
            int ColumnsInterVal = 0;
            int RowsInterVal = 10;
            int LocationX = 25, InitX = 25;
            int LocationY = 25;

            this.pGroup.Size = new Size(450, 70);
            this.btnOK.Location = new Point(150, 30);
            this.btnClose.Location = new Point(240, 30);

            foreach (Control cc in this.pGroup.Controls)
            {
                if (cc is CheckBox) this.pGroup.Controls.Remove(cc);
            }

            DataTable dt = QT.SEO.Group.GetAll();
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                CheckBox cbox = new CheckBox();
                cbox.Location = new Point(LocationX, LocationY);
                cbox.Width = ColumnWidth;
                cbox.Text = dt.Rows[i]["gname"].ToString();
                cbox.Name = dt.Rows[i]["guid"].ToString();
                if (SelectionGroups.Contains(dt.Rows[i]["guid"].ToString())) cbox.Checked = true;
                cbox.CheckedChanged += new EventHandler(cbox_CheckedChanged);
                this.pGroup.Controls.Add(cbox);
                if (i % ColumnsCount == 0)
                {
                    this.pGroup.Height += cbox.Height + RowsInterVal;
                    this.btnOK.Location = new Point(this.btnOK.Location.X, this.btnOK.Location.Y + cbox.Height + RowsInterVal);
                    this.btnClose.Location = new Point(this.btnClose.Location.X, this.btnClose.Location.Y + cbox.Height + RowsInterVal);
                }
                LocationX += cbox.Width + ColumnsInterVal;
                if (i % ColumnsCount == (ColumnsCount - 1))
                {
                    LocationX = InitX;
                    LocationY += cbox.Height + RowsInterVal;
                }
            }

            this.pGroup.Visible = true;
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            if (SelectionGroups.Count == 0)
            {
                MessageBox.Show("请选择要检查的分组");
                return;
            }

            this.lvResult.Items.Clear();
            SetButton(false);
            myThread = new Thread(new ThreadStart(ThreadCheck));
            myThread.Start();
            IsPause = false;
            this.pGroup.Visible = false;

            SelectionGroupNames.Clear();
            SelectionGroups.Clear();
            foreach (Control ctl in this.pGroup.Controls)
            {
                if (ctl is CheckBox)
                {
                    if (((CheckBox)ctl).Checked) SelectionGroups.Add(ctl.Name);
                }
            }

            QT.SEO.Setting.Update("DefaultGroupForCheckSnapShot", string.Join("|", SelectionGroups.ToArray()));
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.pGroup.Visible = false;
        }

        public void cbox_CheckedChanged(object sender, EventArgs e)
        {
            if (((CheckBox)sender).Checked) SelectionGroups.Add(((CheckBox)sender).Name);
            else SelectionGroups.Remove(((CheckBox)sender).Name);
        }

        private void btnPause_Click(object sender, EventArgs e)
        {
            if (IsPause)
            {
                Threadmre.Set();
                IsPause = false;
                this.btnPause.Text = "暂停";
            }
            else
            {
                Threadmre.Reset();
                IsPause = true;
                this.btnPause.Text = "继续";
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (myThread != null && myThread.IsAlive)
            {
                if (MessageBox.Show("正在进行检查操作，确认要退出吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                {
                    return;
                }
                myThread.Abort();
            }
            SetButton(true);
        }

        #endregion

        #region Label

        private void lblURL_Click(object sender, EventArgs e)
        {
            Setting.URLManage myURL = new Setting.URLManage();
            myURL.ShowDialog();
        }

        private void lblURL_MouseHover(object sender, EventArgs e)
        {
            this.lblURL.ForeColor = Color.Red;
        }

        private void lblURL_MouseLeave(object sender, EventArgs e)
        {
            this.lblURL.ForeColor = SystemColors.ControlText;
        }

        #endregion

        #region PictureBox

        private void pbClose_Click(object sender, EventArgs e)
        {
            if (myThread != null && myThread.IsAlive)
            {
                if (MessageBox.Show("正在进行网址快照检查，确认要关闭吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                {
                    return;
                }

                myThread.Abort();
            }
            ((Main)this.ParentForm).tsslMsg.Text = "";
            ((Main)this.ParentForm).tsslProgress.Text = "";
            this.Dispose();
        }

        private void pbClose_MouseHover(object sender, EventArgs e)
        {
            this.pbClose.Image = Properties.Resources.close02;
        }

        private void pbClose_MouseLeave(object sender, EventArgs e)
        {
            this.pbClose.Image = Properties.Resources.close01;
        }

        #endregion

        #region ListView

        private void lvResult_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ListViewItem item = ((CustomListView)sender).GetItemAt(e.X, e.Y);
                ListViewItem.ListViewSubItem portSubItem = item.GetSubItemAt(e.X, e.Y);
                int intColIndex = item.SubItems.IndexOf(portSubItem);//这个就是列索引了
                switch (intColIndex)
                {
                    case 1:
                        if (item.SubItems[intColIndex].Text.Length > 0) System.Diagnostics.Process.Start((item.SubItems[intColIndex].Text.StartsWith("http://") ? "" : "http://") + item.SubItems[intColIndex].Text);
                        break;
                    case 2://打开网页
                        if (item.SubItems[intColIndex].Text.Length > 0) System.Diagnostics.Process.Start((item.SubItems[intColIndex - 1].Text.StartsWith("http://") ? "" : "http://") + item.SubItems[intColIndex - 1].Text);
                        break;
                    case 3://打开快照页面
                        if (item.SubItems[5].Text.Length > 0) System.Diagnostics.Process.Start((item.SubItems[5].Text.StartsWith("http://") ? "" : "http://") + item.SubItems[5].Text);
                        break;
                    case 4://打开搜索页面
                        if (item.SubItems[intColIndex].Text.Length > 0) System.Diagnostics.Process.Start((item.SubItems[6].Text.StartsWith("http://") ? "" : "http://") + item.SubItems[6].Text);
                        break;
                    default:
                        break;
                }
            }
        }

        #endregion

        #region ToolStripMenuItem

        private void ToolStripMenuItem_Export_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            saveFileDialog1.ValidateNames = true;
            saveFileDialog1.Filter = "日志文件(*.log)|*.log|CSV文件(*.csv)|*.csv";
            saveFileDialog1.FilterIndex = 1;
            saveFileDialog1.DefaultExt = "log";
            saveFileDialog1.FileName = "";
            saveFileDialog1.AddExtension = true;
            if (saveFileDialog1.ShowDialog() == DialogResult.Cancel)
            {
                return;
            }

            if (saveFileDialog1.FileName.EndsWith(".csv"))
            {
                if (QT.SEO.Export.Export2CSV(lvResult, saveFileDialog1.FileName))
                {
                    MessageBox.Show("导出成功");
                }
                else
                {
                    MessageBox.Show("操作失败");
                    return;
                }
            }
            else
            {
                if (QT.SEO.Export.Export2Txt(lvResult, saveFileDialog1.FileName))
                {
                    MessageBox.Show("导出成功");
                }
                else
                {
                    MessageBox.Show("操作失败");
                    return;
                }
            }
        }

        #endregion

        #endregion

        #region Thread&DeleGate

        private void ThreadCheck()
        {
            try
            {
                Threadmre.Set();

                string[] SearchEngines = QT.SEO.Setting.Get("SearchEngine").Split('|');
                string InterVal = QT.SEO.Setting.Get("InterVal");
                this.thisRecord = 0;

                foreach (string SearchEngine in SearchEngines)
                {
                    LastRecord = QT.SEO.SnapShot.GetRecordCount(SelectionGroups, SearchEngine);

                    DataTable dt_Search = QT.SEO.SearchEngine.Get(SearchEngine);
                    string myURI = dt_Search.Rows[0]["uri"].ToString();
                    int codepage = 0;
                    if (!(int.TryParse(dt_Search.Rows[0]["codepage"].ToString(), out codepage))) codepage = 0;

                    DataTable dt_url = QT.SEO.URL.GetAll(SelectionGroups);
                    string ref_url = "";
                    string url = "";
                    InitProgressBar(dt_Search.Rows[0]["SearchName"].ToString(), dt_url.Rows.Count);
                    for (int i = 0; i < dt_url.Rows.Count; i++)
                    {
                        ref_url = url;
                        url = myURI.Replace("{keywords}", dt_url.Rows[i]["url"].ToString());

                        try
                        {
                            string HtmlData = QT.SEO.UrlGather.GetHtml(url, ref_url, Encoding.GetEncoding(codepage)).Replace(" ", "").Replace("\n", "").Replace("\r", "");
                            QT.SEO.SearchResult Result = new QT.SEO.SearchResult();
                            Result = QT.SEO.UrlGather.GetSnapShot(HtmlData, dt_Search.Rows[0], dt_url.Rows[i]["url"].ToString(), Encoding.GetEncoding(codepage));
                            Result.guid = dt_url.Rows[i]["guid"].ToString();
                            Threadmre.WaitOne();
                            myDeleGateListView myDelegate = new myDeleGateListView(SaveResult);
                            this.Invoke(myDelegate, Result, SearchEngine, dt_Search.Rows[0]["SearchName"].ToString(), url);

                            SetProgressBar(dt_Search.Rows[0]["SearchName"].ToString());
                            Thread.Sleep(int.Parse(InterVal) * 1000);
                        }
                        catch
                        {
                            continue;
                        }
                    }
                }
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                Threadmre.WaitOne();
                try
                {
                    this.Invoke(new myDeleGateButton(SetButton), new object[] { true });
                }
                catch (ThreadAbortException)
                {
                }
                catch (InvalidOperationException)
                {
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        #endregion

        #region Method

        private void SetButton(bool b)
        {
            this.btnStart.Enabled = b;
            this.btnPause.Enabled = !b;
            this.btnCancel.Enabled = !b;
        }

        private void SaveResult(QT.SEO.SearchResult Result, string sid, string SearchEngine, string url)
        {
            #region 写入数据库

            int rVal = 0;

            rVal = QT.SEO.SnapShot.Add(Result.guid, Result.date, sid, Result.title, Result.snapshot);

            #endregion

            #region ListView显示

            ListViewItem item = new ListViewItem();
            item.SubItems[0].Text = (this.lvResult.Items.Count + 1).ToString();
            item.SubItems.Add(Result.url);
            item.SubItems.Add(Result.title);
            item.SubItems.Add(Result.date);
            item.SubItems.Add(SearchEngine);
            item.SubItems.Add(Result.snapshot);
            item.SubItems.Add(url);

            item.UseItemStyleForSubItems = true;
            thisRecord++;
            if (rVal == -2)
            {
                item.ForeColor = Color.Gray;
            }
            if (Result.IsSnap == false)
            {
                item.ForeColor = Color.Red;
                thisRecord--;
            }
            this.lvResult.Items.Add(item);

            ToolStripStatusLabel tsslMsg = ((Main)this.ParentForm).tsslMsg;
            tsslMsg.Text = string.Format(FormatMsg, SearchEngine, LastRecord, thisRecord);

            #endregion
        }

        private void InitProgressBar(string s,int Max)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateInitProgressBar(InitProgressBar), new object[] { s, Max });
            }
            else
            {
                ToolStripProgressBar pb = ((Main)this.ParentForm).pbMain;
                ToolStripStatusLabel tsslProgress = ((Main)this.ParentForm).tsslProgress;
                pb.Maximum = Max;
                pb.Value = 0;
                tsslProgress.Text = string.Format(FormatProgress, s, pb.Value, pb.Maximum);                
            }
        }

        private void SetProgressBar(string s)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateSetProgressBar(SetProgressBar), new object[] { s });
            }
            else
            {
                ToolStripProgressBar pb = ((Main)this.ParentForm).pbMain;
                ToolStripStatusLabel tsslProgress = ((Main)this.ParentForm).tsslProgress;
                pb.Value++;
                tsslProgress.Text = string.Format(FormatProgress, s, pb.Value, pb.Maximum);
                Application.DoEvents();
            }
        }

        #endregion

    }
}
